#include "Nodo.h"

/* =============================================================================
 * Declaracion Atributos privados
 * =============================================================================
 */
struct Nodo{
    int id;
    unsigned long int memoria;
    tProcesador procesador;
    unsigned char estado;
};

typedef struct Nodo* _tNodo;

/*==============================================================================
 * Declaracion de metodos privados
 *==============================================================================
 */

static tProcesador nodoGetProcesador(tNodo pNodo);

/*==============================================================================
 * Definicion de metodos publicos
 *==============================================================================
 */

void nodoCrear (tNodo* pNodo, int pId, unsigned long int pMemoriaDisponible){
    
    if (pNodo && pMemoriaDisponible > 0)
    {
        _tNodo nodo = (_tNodo) malloc (sizeof (struct Nodo));
        if (nodo)
        {
            nodo->id = pId;
            nodo->estado = APAGADO;
            nodo->memoria = pMemoriaDisponible;
            procesadorCrear(&(nodo->procesador));
        }
        *pNodo = nodo;
    }
}

//------------------------------------------------------------------------------

int nodoDestruir (tNodo pNodo){

    int val = 0;
    
    if (pNodo)
    {
        _tNodo nodo = (_tNodo) pNodo;
        procesadorDestruir(nodo->procesador);
        free (nodo);
        
        val = 1;
    }
    
    return val;
}

//------------------------------------------------------------------------------

int nodoGetId(tNodo pNodo){

    int val = 0;

    if (pNodo)
        val = ((_tNodo)pNodo)->id;

    return val;
}

//------------------------------------------------------------------------------

unsigned long int nodoGetMemoria (tNodo pNodo){

    unsigned long int  val = 0;

    if (pNodo)
        val = ((_tNodo)pNodo)->memoria;

    return val;
}

//------------------------------------------------------------------------------

tEstadoNodo nodoGetEstado (tNodo pNodo){

    unsigned char val = 0;

    if (pNodo)
        val = ((_tNodo)pNodo)->estado;

    return val;
}

//------------------------------------------------------------------------------

tTrabajo nodoGetTrabajo(tNodo pNodo){
    
    tTrabajo trabajo = NULL;
    
    if (pNodo)
        trabajo = procesadorGetTrabajo(nodoGetProcesador(pNodo));
    
    return trabajo;
}

//------------------------------------------------------------------------------

tEstadoProceso nodoGetEstadoProcesador(tNodo pNodo){
    
    tEstadoProceso estado = FINALIZADO;
    
    if (pNodo)
    {
        if (procesadorEstaCorriendo(nodoGetProcesador(pNodo)))
            estado = CORRIENDO;
    }
    
    return estado;
}

//------------------------------------------------------------------------------

tEstadoNodo nodoEncender (tNodo pNodo){
    
    tEstadoNodo val = APAGADO;
    
    if (pNodo)
    {
        if (APAGADO == nodoGetEstado(pNodo))
        {
            ((_tNodo) pNodo)->estado = ENCENDIDO;
            val = ENCENDIDO;
        }
    }
    
    return val;
}

//------------------------------------------------------------------------------

tEstadoNodo nodoApagar (tNodo pNodo){

    tEstadoNodo val = APAGADO;
    
    if (pNodo)
    {
        if (ENCENDIDO == nodoGetEstado(pNodo))
        {
            if (!procesadorEstaCorriendo(((_tNodo)pNodo)->procesador))
            {
                ((_tNodo) pNodo)->estado = APAGADO;
                val = APAGADO;
            }
            else
                val = ENCENDIDO;
        }
    }
    return val;
}

//------------------------------------------------------------------------------

tBool nodoEsEjecutable(tNodo pNodo, tTrabajo pTrabajo){
    
    tBool val = FALSE;
    
    if (pNodo && pTrabajo)
    {
        if (
                ENCENDIDO == nodoGetEstado(pNodo)
            &&  nodoGetMemoria(pNodo) >= trabajoGetRequerimientoMemoria(pTrabajo)
            &&  !procesadorEstaCorriendo(nodoGetProcesador(pNodo))
           )
            val = TRUE;
    }
    return val;
}

//------------------------------------------------------------------------------

void nodoEjecutar(tNodo pNodo, tTrabajo pTrabajo){
    
    if (pNodo && pTrabajo)
        if (nodoEsEjecutable(pNodo, pTrabajo))
            procesadorSetTrabajo(nodoGetProcesador(pNodo), pTrabajo);
}

//------------------------------------------------------------------------------

//==============================================================================

tProcesador nodoGetProcesador(tNodo pNodo)
{
    tProcesador procesador = NULL;
    
    if (pNodo)
    {
        procesador = ((_tNodo) pNodo)->procesador;
    }
    
    return procesador;
}
